#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <errno.h>

#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"
#include "crypto_func.h"
#include "sm2.h"
#include "tpm2_value.h"
#include "tpm2_global.h"
#include "tpm2_structure.h"
#include "tpm2_command.h"
#include "vtcm_alg.h"

#define MAX_SM3_ARGS 30
#define MAX_SM3_LEN  1024
static BYTE Buf[DIGEST_SIZE*64];

int Init_tpms_PcrSelection(TPMS_PCR_SELECTION * pcr_select)
{
	pcr_select->hash = TPM_ALG_SM3_256;
        pcr_select->sizeOfSelect=IMPLEMENTATION_PCR/8;
	if(pcr_select->pcrSelect ==NULL)
	{
		pcr_select=Talloc0(pcr_select->sizeOfSelect);
		if(pcr_select==NULL)
			return -EINVAL;
	}
        Memset(pcr_select->pcrSelect,0,pcr_select->sizeOfSelect);
        return 0;
}

int Set_tpms_PcrSelection(TPMS_PCR_SELECTION * pcr_select,int index)
{
        int pcr_select_offset;
        BYTE select_value;
        if((index<0) || (index>=IMPLEMENTATION_PCR))
                return -EINVAL;
        pcr_select_offset=index/8;
        select_value=1<<(index%8);
        pcr_select->pcrSelect[pcr_select_offset] |=select_value;
        return 0;
}

int Clear_tpms_PcrSelection(TPMS_PCR_SELECTION * pcr_select,int index)
{
        int pcr_select_offset;
        BYTE select_value;
        if((index<0) || (index>=IMPLEMENTATION_PCR))
                return -EINVAL;
        pcr_select_offset=index/8;
        select_value=1<<(index%8);
        pcr_select->pcrSelect[pcr_select_offset] &=~select_value;
        return 0;
}

int tpml_PcrSelection_add(TPML_PCR_SELECTION * tpml_pcr_select,TPMS_PCR_SELECTION * tpms_pcr_select)
{
	pcr_select->hash = TPM_ALG_SM3_256;
        pcr_select->sizeOfSelect=IMPLEMENTATION_PCR/8;
	if(pcr_select->pcrSelect ==NULL)
	{
		pcr_select=Talloc0(pcr_select->sizeOfSelect);
		if(pcr_select==NULL)
			return -EINVAL;
	}
        Memset(pcr_select->pcrSelect,0,pcr_select->sizeOfSelect);
        return 0;
}

// Init a pcr selection struct
// int vtcm_Init_PcrComposite(TCM_PCR_COMPOSITE * pcr_comp)
// {
//         Memset(pcr_comp,0,sizeof(*pcr_comp));
//                 vtcm_Init_PcrSelection(&pcr_comp->select);
//                         return 0;
//                         }
//
